perm filename SAY3.FAI[SYS,HE] blob
sn#129815 filedate 1974-11-14 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00006 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 ENTRY SAY
C00005 00003 Main speaking loop
C00008 00004 Special control codes
C00010 00005 PHONEME CONVERSION TABLE
C00015 00006 Phoneme modifier table
C00016 ENDMK
C⊗;
ENTRY SAY
TITLE SAY
INTERNAL SAY
EXTERNAL JOBFF
COMMENT⊗ SAIL calling sequence:
PROCEDURE SAY(STRING S)
SAY does an IOPUSH of channel 0, INIT's the voder, does a temporary audio
switch select of the voder channel, speaks out the string, IOPOP's channel 0,
and restores the permanent audio switch mapping.
⊗
IPNT←1 ;Input string pointer
OPNT←2 ;Output pointer
OBUF←3 ;Output buffer (4 9-bit bytes)
LAST←4 ;Last phoneme spoken, in case of a modifier.
LINF←5 ;Inflection of last phoneme
NBYTES←6 ;No. of bytes left in input
CODE←7
TEM←10
PLEVEL←11 ;Permanent inflection level
TLEVEL←13 ;Temporary level
SP←16 ;SAIL pointers
P←17
SAY: CHNSTS 0,TEM
MOVEM TEM,STAT#
TRNN TEM,400000
JRST NOPUSH
IOPUSH 0,0
JRST [ OUTSTR [ASCIZ|No room on I/O PDL -- SAY
|]
EXIT]
NOPUSH: MOVEI TEM,0
OPNIT: INIT 0,410
'VOD '
XWD VBUF,0
JRST WVODR
SETSTS 0,10
MOVEI TEM,BUFR
EXCH TEM,JOBFF
OUTBUF 0,1
MOVEM TEM,JOBFF
POP SP,IPNT ;Get the string pointer.
POP SP,NBYTES
HRRZ NBYTES,NBYTES
MOVEI PLEVEL,1 ;Default inflection is normal.
MOVE OPNT,[POINT 9,OBUF]
MOVEI OBUF,0
MOVEI LAST,0
MOVE TEM,[607010,,0] ;Temporary AS mapping to voder.
ADSMAP TEM,
;End of initialization. Fall through to main loop.
;Main speaking loop
NXTPHN: MOVE TLEVEL,PLEVEL ;New phoneme - set inf. to permanent.
NXTBYT: SOJL NBYTES,FINISH ;End of input string?
ILDB CODE,IPNT ;No. Get next byte.
SKIPL CODE,PHNTAB(CODE)
JRST SPCL ;Special codes have bit 0 off.
REGPHN: MOVE LAST,CODE ;Save code in case of a modifier.
MOVE LINF,TLEVEL
TLNE OPNT,770000 ;Is the one-word buffer full?
JRST PUTIT
SOSG VBUF+2
OUTPUT 0,
IDPB OBUF,VBUF+1
MOVEI OBUF,0
MOVE OPNT,[POINT 9,OBUF]
PUTIT: LDB TEM,[POINT 9,CODE,8] ;Phoneme code is in bits 0:8.
OR TEM,TLEVEL ;Add the inflection bits,
IDPB TEM,OPNT ;and stick it in the buffer.
JRST NXTPHN
SPCL: JUMPN CODE,(CODE) ;Special code. Go do it.
JRST NXTBYT ;Ignore undefined codes.
FINISH: JUMPE OBUF,FIN1 ;All done.
SOSG VBUF+2
OUTPUT 0,
IDPB OBUF,VBUF+1
FIN1: OUTPUT 0, ;Force the last buffer out.
MOVSI OBUF,777000 ;Output a null phoneme
SOS VBUF+2 ;(forces a wait until the
IDPB OBUF,VBUF+1 ;voder finishes talking)
OUTPUT 0,
MOVNI TEM,1
ADSMAP TEM, ;Restore the permanent AS mapping
RELEAS 0, ;and the state of I/O.
MOVE TEM,STAT
TRNE TEM,400000
IOPOP 0,0
JFCL
POPJ P,
WVODR: ;JUST RETURN
POP SP,IPNT ;Get the string pointer.
POP SP,NBYTES
POPJ P,
;Special control codes
DIG: JUMPE LAST,NXTBYT ;Digit 1-3...
LDB CODE,IPNT
ANDI CODE,3
NXTDIG: LDB TEM,MODTAB(CODE) ;pick up the modified phoneme from
JUMPN TEM,PUTDIG ;the last code used. If zero,
SOJG CODE,NXTDIG ;decrease the digit.
JRST NXTBYT ;No modifers allowed. Ignore it.
PUTDIG: OR TEM,LINF ;Got the mod. Add the right inflection,
CAIN TEM,400 ;Avoid EH3 with highest inflection,
MOVEI TEM,401 ;since it hangs the voder
DPB TEM,OPNT ;put it into the buffer.
JRST NXTPHN
SETLVL: HLRZ PLEVEL,CODE ;Absolute level select.
JRST NXTPHN
UPP: HLRZ TEM,CODE ;Up permanent inflection...
SUB PLEVEL,TEM ;subtract the increment,
JUMPGE PLEVEL,NXTPHN ;cut off at 0.
MOVEI PLEVEL,0
JRST NXTPHN
DWNP: HLRZ TEM,CODE ;Down permanently...
ADD PLEVEL,TEM ;add the increment,
CAILE PLEVEL,3 ;cut off at 3.
MOVEI PLEVEL,3
JRST NXTPHN
UPT: SOJGE TLEVEL,NXTBYT ;Up temporarily.
MOVEI TLEVEL,0
JRST NXTBYT
DWNT: ADDI TLEVEL,1 ;Down temporarily.
CAILE TLEVEL,3
MOVEI TLEVEL,3
JRST NXTBYT
WBRK: MOVEI PLEVEL,1
HLLZ CODE,CODE
TLO CODE,400000
JRST REGPHN
;PHONEME CONVERSION TABLE
XALL
;Lower-case letters without pronunciation examples are the same
;as upper case
DEFINE P(A) {BYTE (9)400+A,0,0,0}
DEFINE P1(A,B) {BYTE (9)400+A,400+B,0,0}
DEFINE P2(A,B,C) {BYTE (9)400+A,400+B,400+C,0}
DEFINE P3(A,B,C,D) {BYTE(9)400+A,400+B,400+C,400+D}
PHNTAB:
0 ;000
2,,DWNP ;001 ↓ Down 2 levels
P2 274,310,014 ;002 α AW (lAW)
0 ;003
UPT ;004 ∧ Up for just one
0 ;005
0 ;006
0 ;007
0 ;010
0 ;011
0 ;012
0 ;013
0 ;014
0 ;015
0 ;016
0 ;017
0 ;020
0 ;021
0,,SETLVL ;022 ∩ Highest pitch
3,,SETLVL ;023 ∪ Lowest pitch
P2 044,250,020 ;024 ∀ AH (fAther)
P 204 ;025 ∃ AY (wAve)
0 ;026
0 ;027
2,,SETLVL ;030 _ Low pitch
0 ;031
0 ;032
0 ;033
0 ;034
0 ;035
0 ;036
DWNT ;037 ∨ Down for just one
300000,,WBRK ;040 (SP) Word pause, reset inflection to normal.
0 ;041
P 174 ;042 " Comma pause
0 ;043
0 ;044
0 ;045
0 ;046
P 300 ;047 ' Word pause
0 ;050
0 ;051
0 ;052
0 ;053
174000,,WBRK ;054 , Comma pause, reset inflection to normal.
1,,SETLVL ;055 - normal pitch
0 ;056
1,,UPP ;057 / Upward
0 ;060
DIG ;061 1 Duration modifiers
DIG ;062 2
DIG ;063 3
0 ;064
0 ;065
0 ;066
0 ;067
0 ;070
0 ;071
0 ;072
0 ;073
0 ;074
0 ;075
0 ;076
0 ;077
0 ;100
P2 004,140,240 ;101 A (nAme)
P 160 ;102 B
P 010 ;103 C (CHair)
P 170 ;104 D (Dig)
P1 064,074 ;105 E (kEEp)
P 270 ;106 F
P 070 ;107 G (Go)
P 330 ;110 H
P3 344,320,120,220 ;111 I (sIx)
P 130 ;112 J (Just)
P 230 ;113 K
P 030 ;114 L
P 060 ;115 M
P 260 ;116 N (No)
P2 144,254,054 ;117 O (nO)
P 244 ;120 P
0 ;121
P2 134,324,154 ;122 R (fERn)
P 370 ;123 S
P 124 ;124 T
P1 024,354 ;125 U (tOO)
P 360 ;126 V
P 264 ;127 W
P 234 ;130 X (THink)
P1 224,104 ;131 Y (Yes)
P 110 ;132 Z (Zoo)
0 ;133
1,,DWNP ;134 \ Downward
0 ;135
2,,UPP ;136 ↑ Up 2 levels
0 ;137
0 ;140
P1 164,364 ;141 a (cAt)
P 160 ;142 b
P 010 ;143 c
P 040 ;144 d (noTifiy)
P2 334,100,200,000 ;145 e (tEn) EH3 SUPPRESSED FOR HARDWARE BUG.
P 270 ;146 f
P 070 ;147 g
P 330 ;150 h
P3 344,320,120,220 ;151 i
P 130 ;152 j
P 230 ;153 k
P 030 ;154 l
P 060 ;155 m
P 050 ;156 n (siNG)
P1 350,150 ;157 o (gOt)
P 244 ;160 p
0 ;161
P2 134,324,154 ;162 r
P 210 ;163 s
P 124 ;164 t
P3 314,114,214,304 ;165 u (rUn)
P 360 ;166 v
P 264 ;167 w
P 034 ;170 x (THose)
P1 224,104 ;171 y
P 340 ;172 z (aZure)
0 ;173
0 ;174
0 ;175
0 ;176
0 ;177
;Phoneme modifier table
COMMENT⊗
The digits 1-3 after a vowel select shorter versions of the
basic phoneme. The base code is in the first 9 bits of the conversion
table entry, and the shorter versions are in successive 9-bit bytes.
If you use a digit that is larger than the highest-numbered version
of the phoneme, you will get the highest-numbered one that exists.
⊗
MODTAB: POINT 9,LAST,8 ;Base phoneme
POINT 9,LAST,17 ;Mod 1
POINT 9,LAST,26 ;Mod 2
POINT 9,LAST,35 ;Mod 3
VBUF: BLOCK 3
BUFR: BLOCK =23
END